<?php
//******************************************************************
class formConstructor {
	public $formName = null;
	public $formTitle = "";
	public $actionURL = null;
	public $formMethod = "post";
	public $fields = array();
	public $errors = null;
	public $module = null;
	
	public function __construct($module, $formName, $actionURL, $formTitle="", $formMethod="post") {
		$this->formName = $formName;
		$this->formTitle = $formTitle;
		$this->actionURL = $actionURL;
		$this->formMethod = $formMethod;
		$this->module = $module;
	}
	
	public function write() {
		$this->module->engine->addTemplate(WIDGETS_TEMPLATES_PATH."formConstructor.xsl");

		$formsCount = count($this->module->xml->formConstructor);
		$this->module->xml->formConstructor[$formsCount] = "";
		$this->module->xml->formConstructor[$formsCount]['actionURL'] = $this->actionURL;
		$this->module->xml->formConstructor[$formsCount]['formName'] = $this->formName;
		$this->module->xml->formConstructor[$formsCount]['formTitle'] = $this->formTitle;
		$this->module->xml->formConstructor[$formsCount]['formMethod'] = $this->formMethod;
		
		$i = 0;
		foreach ($this->fields as $fieldName => $field) {
			$this->module->xml->formConstructor[$formsCount]->field[$i] = "";
			$field['obj']->xml = $this->module->xml->formConstructor[$formsCount]->field[$i]->children();
			$field['obj']->write();
			$this->module->engine->addTemplate(WIDGETS_TEMPLATES_PATH.$field['obj']->getTemplate().".xsl");
			$i++;
		}
	}
	
	public function addField($fieldName, $fieldTitle, $fieldObj, $fieldDescription="") {
		$fieldName = (empty($fieldName))?"_f".counter('fnnf'):$fieldName;
		$fieldObj->name = $fieldName;
		$fieldObj->title = $fieldTitle;
		$fieldObj->description = $fieldDescription;

		$this->fields[$fieldName] = array('title'=>$fieldTitle,'description'=>$fieldDescription,'obj'=>$fieldObj);
	}
	
	public function submit() {
		if (isset($_REQUEST[$this->formName.'IsSubmit'])) {
			foreach ($this->fields as $fieldName=>$field) {
				$field['obj']->load();
				if ($field['obj']->error) {
					$this->errors[$fieldName] = true;
				}
			}
			return true;
		} else {
			return false;
		}
	}
	
	public function getValue($fieldName) {
		if (isset($this->fields[$fieldName])) {
			return $this->fields[$fieldName]['obj']->getValue();
		} else {
			return null;
		}
	}
	
	public function getAllValues($absolute=false) {
		$values = array();
		foreach ($this->fields as $fieldName=>$field) {
			if(!(substr($fieldName,0,1)=="_" and !$absolute))
				$values[$fieldName] = $this->getValue($fieldName);
		}
		return $values;
	}
	
	public function setValue($fieldName, $value) {
		if (isset($this->fields[$fieldName])) {
			$this->fields[$fieldName]['obj']->setValue($value);
		}
	}
	
	public function setValues($values) {
		if (is_array($values)) {
			foreach ($values as $k=>$v) {
				$this->setValue($k, $v);
			}
		}
	}
	
	public function addError($fieldName) {
		$this->fields[$fieldName]['obj']->error = true;
		$this->errors[$fieldName] = true;
	}

	public function deleteError($fieldName) {
		$this->fields[$fieldName]['obj']->error = false;
		$this->errors[$fieldName] = false;
	}
}
//******************************************************************
class formField {
	protected $value = null;
	public $name = null;
	public $error = false;
	public $title = null;
	public $description = null;
	public $xml = null;
	
	public function load() {
		if (isset($_REQUEST[$this->name])) {
			$this->value = $_REQUEST[$this->name];
		}
		$this->check($this->value);
	}
	
	public function check($value) {
		$this->error = false;
	}
	
	public function write() {
		$this->xml['name'] = $this->name;
		$this->xml['type'] = get_class($this);
		$this->xml['title'] = $this->title;
		$this->xml['description'] = $this->description;
		if ($this->error) $this->xml['error'] = 1;
		$this->xml['value'] = (string)$this->value;
	}
	
	public function getValue() {
		return $this->value;
	}
	
	public function setValue($value) {
		$this->value = $value;
	}
	
	public function getTemplate() {
		return get_class($this);
	}
}
//******************************************************************
class formString extends formField {
	public $regExp = "";
	
	public function __construct($regExp="/.*/") {
		$this->regExp = $regExp;
	}
	
	public function check($value) {
		$this->error = !(preg_match($this->regExp, $value));
	}
}
//******************************************************************
class formPassword extends formField { }
//******************************************************************
class formSubmit extends formField { }
//******************************************************************
class formHidden extends formField {
	public function __construct($value) {
		$this->value = $value;
	}
}
//******************************************************************
class formRadio extends formField {
	protected $possibleValues = array();
	
	public function __construct($possibleValues) {
		$this->possibleValues = $possibleValues;
	}
	
	public function check($value) {
		$this->error = !array_key_exists($value, $this->possibleValues);
	}
	
	public function write() {
		parent::write();
		$i = 0;
		foreach ($this->possibleValues as $k => $v) {
			$this->xml->option[$i] = $v;
			$this->xml->option[$i]['value']=$k;
			if ($this->value == $k) {
				$this->xml->option[$i]['selected'] = 1;
			}
			$i++;
		}
	}
}
//******************************************************************
class formSelectOne extends formRadio { }
//******************************************************************
class formCheckbox extends formField {
	protected $valueComment = "";
	
	public function __construct($valueComment="") {
		$this->valueComment = $valueComment;
	}
	
	public function load() {
		$this->value = isset($_REQUEST[$this->name]);
	}
	
	public function write() {
		parent::write();
		if ($this->value) $this->xml['checked'] = 1;
		$this->xml['comment'] = $this->valueComment;
	}
}
//******************************************************************
class formCheckboxGroup extends formField {
	protected $possibleValues = array();
	protected $returnString = false;
	
	public function __construct($possibleValues, $returnString=false) {
		$this->possibleValues = $possibleValues;
		$this->returnString = $returnString;
	}

	public function load() {
		$this->value = array();
		foreach ($this->possibleValues as $k => $v) {
			$this->value[$k] = isset($_REQUEST[$this->name.'_'.$k]);
		}
	}
	
	public function getValue() {
		if ($this->returnString) {
			return implode(",", array_keys(parent::getValue(),true));
		} else {
			return parent::getValue();
		}
	}
	
	public function setValue($value) {
		if (is_array($value)) {
			parent::setValue($value);
		} else {
			$values = explode(",", $value);
			foreach ($this->possibleValues as $k => $v) {
				if (in_array((string)$k, $values, true)) {
					$this->value[$k] = true;
				} else {
					$this->value[$k] = false;
				}
			}
		}
	}

	public function write() {
		parent::write();
		foreach ($this->possibleValues as $k => $v) {
			$this->xml->box[counter('chbx_'.$this->name)] = $v;
			$this->xml->box[counter('chbx_'.$this->name, false)]['name'] = $k;
			if ($this->value[$k]) $this->xml->box[counter('chbx_'.$this->name, false)]['checked'] = 1;
		}
	}
}
//******************************************************************
class formCalendarUnixTimestamp extends formField {
	public $format = null;
	
	public function __construct($format='%Y-%m-%d %H:%M', $defaulDate=null) {
		$this->value = ($defaulDate===null)?strftime($format):strftime($format, $defaulDate);
		$this->format = $format;
	}
	
	public function write() {
		parent::write();
		$this->xml->calendarScriptsNeeded = "";
		$this->xml['format'] = $this->format;
		$this->xml['showsTime'] = (strpos($this->format,'%H')!==false)?'true':'false';
	}
	
	public function getValue() {
		$strptime = strptime($this->value, $this->format);
		$strptime['tm_year'] = $strptime['tm_year'] + 1900;
		$strptime['tm_mon'] = $strptime['tm_mon'] + 1;
		$time = mktime($strptime['tm_hour'], $strptime['tm_min'], $strptime['tm_sec'], $strptime['tm_mon'], $strptime['tm_mday'], $strptime['tm_year']);
		return $time;
	}
	
	public function setValue($value) {
		if ($value == "") {
			$this->value = "";
		} else {
			$this->value = strftime($this->format, $value);
		}
	}
}
//******************************************************************
class formCalendarDateTime extends formCalendarUnixTimestamp {
	public function getValue() {
		return strftime(DB_DATETIME_FORMAT, parent::getValue());
	}
	
	public function setValue($value) {
		if ($value == "") {
			$this->value = "";
		} else {
			$this->value = strftime($this->format, strtotime($value));
		}
	}
	
	public function getTemplate() {
		return 'formCalendarUnixTimestamp';
	}
}
//******************************************************************
class formTextarea extends formField {
	public $cols;
	public $rows;
	
	public function __construct($cols=80, $rows=5) {
		$this->cols = $cols;
		$this->rows = $rows;
	}

	public function write() {
		$this->xml['name'] = $this->name;
		$this->xml['type'] = get_class($this);
		$this->xml['title'] = $this->title;
		$this->xml['description'] = $this->description;
		if ($this->error) $this->xml['error'] = 1;
		
		$this->xml['cols'] = $this->cols;
		$this->xml['rows'] = $this->rows;
		$this->xml[0] = (strlen($this->value)>0)?$this->value:" ";
	}
}
//******************************************************************
class formVisualEditor extends formTextarea {
	public $allowedTags = null;
	
	public function __construct($cols=80, $rows=5, $allowedTags="<a><b><strong><u><s><strike><big><small><h1><h2><h3><h4><i><em><img><li><ol><ul><p><br><div><span><pre><sup><sub><hr>") {
		parent::__construct($cols, $rows);
		$this->allowedTags = $allowedTags;
	}

	public function load() {
		parent::load();
		$this->value = strip_tags($this->value, $this->allowedTags);
	}

	public function write() {
		parent::write();
		$this->xml->visualEditorScriptsNeeded = "";
	}
}
//******************************************************************
class formSeparator extends formField {
	public function load() { }
	public function write() {
		$this->xml['type'] = get_class($this);
		$this->xml['title'] = $this->title;
	}
}
//******************************************************************
class formFileUpload extends formField {
	public $allowedTypes = null;
	public $required = null;
	
	public function __construct($required=false, $allowedTypes=array("image/png", "image/gif", "image/jpeg")) {
		$this->allowedTypes = $allowedTypes;
		$this->required = $required;
	}
	
	public function load() {
		if (isset($_FILES[$this->name])) {
			$this->value = $_FILES[$this->name];
		}
		$this->check($this->value);
	}
	
	public function check($value) {
		if ($value['error'] > 0 || (!in_array($value['type'], $this->allowedTypes) && !in_array("*", $this->allowedTypes))) {
			$this->error = true;
		}
		if (!$this->required && $value['error'] == 4) {
			$this->error = false;
		}
	}
}
//******************************************************************
?>